
    /*
     * While you can use #inherit to extend one constructors prototype
     * by another, there are times when inheritence is perhaps not the best
     * solution to confer traits (i.e. properties) to an object. Or perhaps
     * there are times when you want to make use of a form of multiple inheritance.
     * 
     * In the example below, we have four classes, Setter, Getter, Finder and
     * Mixin. Mixin inherits from Finder, and borrows from Setter and Getter,
     * using the constructor logic of these three classes in its own constructor.
     * 
     * While Mixin instances will qualify as instances of Finder (due to 
     * inheritance), mixin instances will not qualify as instances of Setter or
     * Getter, even though it has the same methods as these two classes.
     * 
     */
    
    /////////////////////////////////////////
    
    Setter.implement
    (
        function setProperty (name, value) 
        {
            if (this.classPropertiesOnly && this.hasOwnProperty(name))
                return;
                
            this[name]= value;
        }
    );
    
    function Setter (classPropertiesOnly) 
    {
        this.classPropertiesOnly= !!classPropertiesOnly;
    };
    
    /////////////////////////////////////////
    
    Getter.implement
    (
        function getProperty (name) 
        {
            if (name in this)
                return this[name];
            
            if (this.throwErrorIfNotFound)    
                throw new ReferenceError ('Undefined property "' + name + '"');
        }
    );
    
    function Getter (throwErrorIfNotFound)
    {
        this.throwErrorIfNotFound= !!throwErrorIfNotFound;
    };
    
    /////////////////////////////////////////
    
    Finder.implement
    (
        function hasProperty (name) 
        {
            if (this.hidePrivate)
                if (/_/.test(name))
                    return false;
                    
            return name in this;
        }
    );
    
    function Finder (hidePrivate) 
    {
        this.hidePrivate= !!hidePrivate;
    };
    
    /////////////////////////////////////////
    
    // inherit from Finder
    Mixin.inherit(Finder).implement
    (
        // borrow Setters traits
        Setter.prototype
        // borrow Getters traits
    ,   Getter.prototype
    );
    
    // Mixin now has the following methods- hasProperty, getProperty and setProperty
    
    /**
     * @constructor
     * 
     * Create a new Mixin instance.
     * 
     * @param {Boolean} throwErrorIfNoProperty    Whether getProperty returns null or throws an error
     * @param {Boolean} classPropertiesOnly       Whether setProperty will only set inherited properties
     * @param {Boolean} hidePrivate               Whether hasProperty will lie about private properties
     */
    function Mixin (throwErrorIfNoProperty, classPropertiesOnly, hidePrivate) 
    {
        // apply Getters constructor logic to this instance
        Getter.call(this, throwErrorIfNoProperty);
        // apply Setters constructor logic to this instance
        Setter.call(this, classPropertiesOnly);
        // apply Finders constructor logic to this instance
        Finder.call(this, hidePrivate);
    };
    

